package com.uniontech.template.config;

import com.alibaba.fastjson.serializer.*;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
//import com.uniontech.iso.interceptor.AuthInterceptor;
//import com.uniontech.iso.interceptor.CurrentUserMethodArgumentResolver;
//import com.uniontech.iso.interceptor.ErrorInterceptor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.lang.reflect.Type;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.TimeZone;

@Configuration
public class WebConfig extends WebMvcConfigurationSupport {


    private final String[] allowUrls = new String[]{"/**"};

    @Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}")
    private String dateFormat;
    @Value("${spring.jackson.time-zone:Asia/Shanghai}")
    private String dateZone;

    @PostConstruct
    private void setDefaultTimezone() {
        TimeZone.setDefault(TimeZone.getTimeZone(dateZone));
    }

    /*
     * 先把JackSon的消息转换器删除. 32 备注: (1)源码分析可知，返回json的过程为: 33
     * Controller调用结束后返回一个数据对象，for循环遍历conventers，找到支持application/
     * json的HttpMessageConverter，然后将返回的数据序列化成json。 34
     * 具体参考org.springframework.web.servlet.mvc.method.annotation.
     * AbstractMessageConverterMethodProcessor的writeWithMessageConverters方法 35
     * (2)由于是list结构，我们添加的fastjson在最后。因此必须要将jackson的转换器删除，不然会先匹配上jackson，
     * 导致没使用fastjson
     */
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        super.configureMessageConverters(converters);
        for (int i = converters.size() - 1; i >= 0; i--) {
            if (converters.get(i) instanceof MappingJackson2HttpMessageConverter) {
                converters.remove(i);
            }
        }
        FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
        // 自定义fastjson配置
        FastJsonConfig config = new FastJsonConfig();
        config.setSerializerFeatures(SerializerFeature.WriteMapNullValue, // 是否输出值为null的字段,默认为false,我们将它打开
                SerializerFeature.WriteNullListAsEmpty, // 将Collection类型字段的字段空值输出为[]
                SerializerFeature.WriteNullStringAsEmpty, // 将字符串类型字段的空值输出为空字符串
                SerializerFeature.WriteNullNumberAsZero, // 将数值类型字段的空值输出为0
                SerializerFeature.PrettyFormat,
                SerializerFeature.WriteDateUseDateFormat,
                SerializerFeature.DisableCircularReferenceDetect // 禁用循环引用
        );
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern(dateFormat);
        SerializeConfig.getGlobalInstance().put(LocalDateTime.class, new ObjectSerializer() {
            @Override
            public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType,
                              int features) throws IOException {
                SerializeWriter out = serializer.getWriter();
                if (object == null) {
                    serializer.getWriter().writeNull();
                    return;
                }
                out.write("\"" + dtf.format((LocalDateTime) object) + "\"");

            }
        });

        fastJsonHttpMessageConverter.setFastJsonConfig(config);
        // 添加支持的MediaTypes;不添加时默认为*/*,也就是默认支持全部
        // 但是MappingJackson2HttpMessageConverter里面支持的MediaTypes为application/json
        // 参考它的做法, fastjson也只添加application/json的MediaType
        List<MediaType> fastMediaTypes = new ArrayList<>();
        fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
        fastJsonHttpMessageConverter.setSupportedMediaTypes(fastMediaTypes);
        converters.add(fastJsonHttpMessageConverter);
    }

//	@Bean
//	AuthInterceptor loginInterceptor() {
//		return new AuthInterceptor();
//	}
//
//	@Bean
//	ErrorInterceptor errorInterceptor() {
//		return new ErrorInterceptor();
//	}
//	@Override
//	public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
//		configurer.favorPathExtension(false);
//	}

//	@Override
//	public void addInterceptors(InterceptorRegistry registry) {
//		registry.addInterceptor(errorInterceptor()).addPathPatterns(allowUrls);
//		registry.addInterceptor(loginInterceptor()).addPathPatterns(allowUrls);
//
//	}

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        for (String url : allowUrls) {
            registry.addMapping(url).allowedHeaders("*").allowedMethods("POST", "GET", "OPTIONS").allowedOrigins("*");
        }
        super.addCorsMappings(registry);
    }

//	@Override
//	public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
//		argumentResolvers.add(currentUserMethodArgumentResolver());
//		super.addArgumentResolvers(argumentResolvers);
//	}
//
//	@Bean
//	public CurrentUserMethodArgumentResolver currentUserMethodArgumentResolver() {
//		return new CurrentUserMethodArgumentResolver();
//	}


}
